dart:ffi を使用したネイティブ Android コードへのバインド
Flutter モバイル アプリとデスクトップ アプリでは、ダーツ:ffiネイティブ C API を呼び出すためのライブラリ。FFIを意味する外部関数インターフェイス。同様の機能を表すその他の用語には次のものがあります。ネイティブインターフェースと言語のバインディング。
ライブラリまたはプログラムが FFI ライブラリを使用できるようになる前に ネイティブ コードにバインドするには、次のことを確認する必要があります。 ネイティブ コードがロードされ、そのシンボルが Dart に表示されます。 このページはコンパイル、パッケージ化、 Flutter プラグインまたはアプリ内で Android ネイティブ コードをロードします。
このチュートリアルでは、C/C++ をバンドルする方法を説明します。 Flutter プラグイン内のソースを使用してバインドします。 Android と iOS の両方にある Dart FFI ライブラリ。 このチュートリアルでは、C 関数を作成します 32ビット加算を実装し、 「native_add」という名前の Dart プラグインを通じてそれを公開します。
動的リンクと静的リンク
ネイティブ ライブラリはアプリにリンクできます。 動的または静的に。静的にリンクされたライブラリ アプリの実行可能イメージに埋め込まれており、 アプリの起動時に読み込まれます。
静的にリンクされたライブラリのシンボルは、
を使用してロードされましたDynamicLibrary.executable
またDynamicLibrary.process
。
対照的に、動的にリンクされたライブラリは分散されます。
アプリ内の別のファイルまたはフォルダーに、
そしてオンデマンドで読み込まれます。 Android では、動的に
リンクされたライブラリは、次のセットとして配布されます。.so
(妖精)
ファイル (アーキテクチャごとに 1 つ)。
動的にリンクされたライブラリは、
ダーツヴィアDynamicLibrary.open
。
API ドキュメントは Dart 開発チャネルから入手できます。Dart API リファレンス ドキュメント。
Android では、動的ライブラリのみがサポートされます (主な実行可能ファイルは JVM であるため、 これには静的にリンクしません)。
FFI プラグインを作成する
「native_add」という FFI プラグインを作成するには、 以下をせよ:
$ flutter create --platforms=android,ios,macos,windows,linux --template=plugin_ffi native_add
$ cd native_add
これにより、C/C++ ソースを含むプラグインが作成されます。native_add/src
。
これらのソースは、さまざまなネイティブ ビルド ファイルによってビルドされます。
OSのビルドフォルダー。
FFI ライブラリは C シンボルに対してのみバインドできます。
したがって、C++ では、これらのシンボルはマークされますextern "C"
。
また、次のことを示す属性も追加する必要があります。
シンボルは Dart から参照されます。
リンカーがシンボルを破棄しないようにするため
リンク時の最適化中。__attribute__((visibility("default"))) __attribute__((used))
。
Android では、native_add/android/build.gradle
コードをリンクします。
ネイティブコードはdartから呼び出されますlib/native_add_bindings_generated.dart
。
バインディングは次のように生成されます。パッケージ:figen。
その他の使用例
プラットフォームライブラリ
プラットフォーム ライブラリにリンクするには、 次の手順を使用してください。
- 目的のライブラリを見つけます。Android NDK ネイティブ APIAndroid ドキュメントのリストを参照してください。これは安定したネイティブ API のリストです。
-
次を使用してライブラリをロードします
DynamicLibrary.open
。 たとえば、OpenGL ES (v3) をロードするには:DynamicLibrary.open('libGLES_v3.so');
Android マニフェストの更新が必要になる場合があります で示されている場合、アプリまたはプラグインのファイル ドキュメント。
ファーストパーティライブラリ
ネイティブコードをソースに組み込むプロセス コードまたはバイナリ形式がアプリで同じであるか、 プラグイン。
オープンソースのサードパーティ
フォローしてくださいC および C++ コードをプロジェクトに追加するAndroid ドキュメントの指示に従って、
ネイティブ コードとネイティブのサポートを追加する
コード ツールチェーン (CMake またはndk-build
)。
クローズドソースのサードパーティライブラリ
Dart を含む Flutter プラグインを作成するには ソース コードですが、C/C++ ライブラリを配布します バイナリ形式では、次の手順を使用します。
- を開きます
android/build.gradle
あなたのファイル 計画。 - AAR アーティファクトを依存関係として追加します。やめてくださいアーティファクトを含めます flutterパッケージ。代わりに、そうあるべきです リポジトリからダウンロードされたものなど Jセンター。
Android APK サイズ (共有オブジェクト圧縮)
Android のガイドライン一般的にお勧めします ネイティブ共有オブジェクトを非圧縮で配布する それは実際にデバイスのスペースを節約できるからです。 共有オブジェクトはAPKから直接ロードできます デバイス上でそれらを解凍する代わりに、 一時的な場所に置いてからロードします。 APK は輸送中にさらに梱包されます。 ダウンロード サイズを確認する必要がある理由。
Flutter APK はデフォルトでこれらのガイドラインに従っていません
そして圧縮するlibflutter.so
とlibapp.so
-これ
APK サイズは小さくなりますが、デバイス サイズは大きくなります。
サードパーティからの共有オブジェクトにより、このデフォルトが変更される可能性があります
で設定android:extractNativeLibs="true"
彼らの中でAndroidManifest.xml
の圧縮を停止しますlibflutter.so
、libapp.so
、およびユーザーが追加した共有オブジェクト。
圧縮を再度有効にするには、次の設定をオーバーライドします。your_app_name/android/app/src/main/AndroidManifest.xml
次の方法で。
@@ -1,5 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.your_app_name">
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.example.your_app_name" >
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
@@ -8,7 +9,9 @@
<application
android:name="io.flutter.app.FlutterApplication"
android:label="your_app_name"
- android:icon="@mipmap/ic_launcher">
+ android:icon="@mipmap/ic_launcher"
+ android:extractNativeLibs="true"
+ tools:replace="android:extractNativeLibs">